#!/usr/bin/env python

# viewerkw.py - This is a LSL2dfg.py output module generating keywords for a keywords.ini viewer file.
#
# (C) Copyright 2013 Sei Lisa.
# Sei Lisa is the author's username in the Second Life online virtual world.
#
# This file is part of LSL2 Derived Files Generator.
#
#    LSL2 Derived Files Generator is free software: you can redistribute it
#    and/or modify it under the terms of the GNU Lesser General Public License
#    as published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    LSL2 Derived Files Generator is distributed in the hope that it will be
#    useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public License
#    along with LSL2 Derived Files Generator. If not, see
#    <http://www.gnu.org/licenses/>.
#
# Second Life is a trademark of Linden Research, Inc.


# Input file should contain lines like:
#     <<< XXX KEYWORDS version >>>            to insert the version comment
#     <<< XXX KEYWORDS sections >>>           to insert the section keywords
#     <<< XXX KEYWORDS types >>>              to insert the types
#     <<< XXX KEYWORDS events >>>             to insert the events
#     <<< XXX KEYWORDS integer constants >>>  to insert the integer constants
#     <<< XXX KEYWORDS string constants >>>   to insert the string constants
#     <<< XXX KEYWORDS float constants >>>    to insert the float constants
#     <<< XXX KEYWORDS compound constants >>> to insert the vector and rotation constants
#     <<< XXX KEYWORDS flow >>>               to insert the flow control keywords
#     <<< XXX KEYWORDS other >>>              to insert all other keywords
#
# (XXX is the tag parameter, default is empty)


import sys

def output(document, defaultdescs, databaseversion, infilename, outfilename, lang, tag):

  version = "0.0.20130101000"

  def outelement(name, tabpos):
    if name in descs:
      desc = descs[name]
    else:
      desc = defaultdescs[lang]

    tabcount = (tabpos - len(name) - 1) // tabsize + 1
    if tabcount < 1: tabcount = 1
    outf.write(name + "\t" * tabcount + desc.replace("\n", ":") + "\n")


  tabsize = 4
  tabpos = 16 # position up to which to output tabs
  tabpos2 = 20 # there's more than one criterion

  if lang not in defaultdescs:
    defaultdescs[lang] = defaultdescs["default"]

  sectionkeywords = []
  flowkeywords = []
  otherkeywords = []
  types = []
  iconstants = []
  sconstants = []
  fconstants = []
  cconstants = []
  #functions = []
  events = []

  descs = {}

  for element in document:
    if element["cat"] == "keyword":
      if element["name"] in ("default", "state"):
        sectionkeywords.append(element["name"])
      elif element["name"] in ("for", "do", "while", "if", "else", "jump", "return"):
        flowkeywords.append(element["name"])
      else:
        otherkeywords.append(element["name"])
    elif element["cat"] == "type":
      types.append(element["name"])
    elif element["cat"] == "constant":
      if element["type"] == "integer":
        iconstants.append(element["name"])
      elif element["type"] == "string":
        sconstants.append(element["name"])
      elif element["type"] == "float":
        fconstants.append(element["name"])
      else:
        cconstants.append(element["name"])
    elif element["cat"] == "event":
      events.append(element["name"])

    if element["cat"] != "function" and "desc" in element and lang in element["desc"]:
      desc = element["desc"][lang]["text"]
      if ":" in desc:
        raise Exception('Element "' + element["name"] + '": Output in keywords.ini format does not support colons in descriptions. Colons in keywords.ini are used as line breaks.')

      heading = ""
      if element["cat"] == "event":

        if "params" in element:
          for param in element["params"]:
            ptype = param["type"]
            heading = heading + ", " + ptype + " " + param["name"]
        heading = element["name"] + "(" + heading[2:] + ")\n"

      descs[element["name"]] = heading + desc

  if infilename is not None:
    inf = open(infilename, "r")
  else:
    inf = sys.stdin

  try:
    inputlines = inf.readlines()

  finally:
    if infilename is not None:
      inf.close()

  if outfilename is not None:
    outf = open(outfilename, "w")
  else:
    outf = sys.stdout

  try:

    for line in inputlines:
      if line.startswith("<<< %s KEYWORDS version >>>" % tag):
        outf.write("# Generated by LSL2 Derived Files Generator. Database version: %s; output module version: %s\n"
          % (databaseversion, version))

      elif line.startswith("<<< %s KEYWORDS sections >>>" % tag):
        for element in sectionkeywords:
          outelement(element, tabpos)

      elif line.startswith("<<< %s KEYWORDS types >>>" % tag):
        for element in types:
          outelement(element, tabpos)

      elif line.startswith("<<< %s KEYWORDS events >>>" % tag):
        for element in events:
          outelement(element, tabpos)

      elif line.startswith("<<< %s KEYWORDS integer constants >>>" % tag):
        for element in iconstants:
          outelement(element, tabpos2)

      elif line.startswith("<<< %s KEYWORDS string constants >>>" % tag):
        for element in sconstants:
          outelement(element, tabpos2)

      elif line.startswith("<<< %s KEYWORDS float constants >>>" % tag):
        for element in fconstants:
          outelement(element, tabpos2)

      elif line.startswith("<<< %s KEYWORDS compound constants >>>" % tag):
        for element in cconstants:
          outelement(element, tabpos2)

      elif line.startswith("<<< %s KEYWORDS flow >>>" % tag):
        for element in flowkeywords:
          outelement(element, tabpos2)

      elif line.startswith("<<< %s KEYWORDS other >>>" % tag):
        for element in otherkeywords:
          outelement(element, tabpos2)

      else:
        outf.write(line)

  finally:
    if outfilename is not None:
      outf.close()


pass
